package com.zzg.mybatis.generator.controller;

import com.zzg.mybatis.generator.model.GeneratorConfig;
import com.zzg.mybatis.generator.util.ConfigHelper;
import com.zzg.mybatis.generator.view.AlertUtil;
import javafx.collections.FXCollections;
import javafx.fxml.FXML;
import javafx.scene.Cursor;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
import javafx.stage.DirectoryChooser;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.net.URL;
import java.util.List;
import java.util.Optional;
import java.util.ResourceBundle;

public class GeneratorConfigController extends BaseFXController {
    private static final Logger _LOG = LoggerFactory.getLogger(GeneratorConfigController.class);
    public MainUIController mainController;

    @FXML
    private TableView<GeneratorConfig> configTable;
    @FXML
    private TableColumn nameColumn;
    @FXML
    private TableColumn opsColumn;
    @FXML
    private TextField txtUniqueName;
    @FXML
    private TextField txtProjectDirectory;
    @FXML
    private TextField txtClassPackage;
    @FXML
    private TextField txtClassDirectory;
    @FXML
    private TextField txtInterfacePackage;
    @FXML
    private TextField txtInterfaceDirectory;
    @FXML
    private TextField txtXmlPackage;
    @FXML
    private TextField txtXmlDirectory;
    @FXML
    private TextField txtPrimaryKey;
    @FXML
    private CheckBox offsetLimitCheckBox;
    @FXML
    private CheckBox commentCheckBox;
    @FXML
    private CheckBox needToStringHashcodeEquals;
    @FXML
    private CheckBox annotationCheckBox;
    @FXML
    private CheckBox useActualColumnNamesCheckbox;
    @FXML
    private CheckBox xmlWithMapperCheckBox;
    @FXML
    private CheckBox xmlWithAnnotationCheckBox;

    @FXML
    public void chooseProjectFolder() {
        DirectoryChooser directoryChooser = new DirectoryChooser();
        File selectedFolder = directoryChooser.showDialog(getPrimaryStage());
        if (selectedFolder != null) {
            this.txtProjectDirectory.setText(selectedFolder.getAbsolutePath());
        }
    }

    private GeneratorConfigController controller;


    private String validateConfig() {
        String projectFolder = txtProjectDirectory.getText();
        if (StringUtils.isEmpty(projectFolder)) {
            return "项目目录不能为空";
        }
        if (StringUtils.isAnyEmpty(txtClassPackage.getText(), txtXmlPackage.getText(), txtInterfacePackage.getText())) {
            return "包名不能为空";
        }

        return null;
    }

    @FXML
    public void handleSubmitButtonAction() {
        GeneratorConfig generatorConfig = getGeneratorConfigFromUI();
        if (StringUtils.isNotBlank(generatorConfig.getName())) {
            try {
                ConfigHelper.updateGeneratorConfig(generatorConfig);
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            TextInputDialog dialog = new TextInputDialog("");
            dialog.setTitle("保存当前配置");
            dialog.setContentText("请输入配置名称");
            Optional<String> result = dialog.showAndWait();
            if (result.isPresent()) {
                String name = result.get();
                if (StringUtils.isEmpty(name)) {
                    AlertUtil.showErrorAlert("名称不能为空");
                    return;
                }
                if (StringUtils.isNotBlank(this.validateConfig())) {
                    AlertUtil.showErrorAlert(this.validateConfig());
                    return;
                }
                _LOG.info("user choose name: {}", name);
                try {
                    generatorConfig.setName(name);
                    ConfigHelper.saveGeneratorConfig(generatorConfig);
                } catch (Exception e) {
                    AlertUtil.showErrorAlert("删除配置失败");
                }
            }
        }

        refreshTableView();
    }

    public GeneratorConfig getGeneratorConfigFromUI() {
        GeneratorConfig generatorConfig = new GeneratorConfig();
        generatorConfig.setName(txtUniqueName.getText());
        generatorConfig.setProjectFolder(txtProjectDirectory.getText());
        generatorConfig.setModelPackage(txtClassPackage.getText());
        generatorConfig.setGenerateKeys(txtPrimaryKey.getText());
        generatorConfig.setModelPackageTargetFolder(txtClassDirectory.getText());
        generatorConfig.setDaoPackage(txtInterfacePackage.getText());
        generatorConfig.setDaoTargetFolder(txtInterfaceDirectory.getText());
        generatorConfig.setMappingXMLPackage(txtXmlPackage.getText());
        generatorConfig.setMappingXMLTargetFolder(txtXmlDirectory.getText());
        generatorConfig.setOffsetLimit(offsetLimitCheckBox.isSelected());
        generatorConfig.setComment(commentCheckBox.isSelected());
        generatorConfig.setNeedToStringHashcodeEquals(needToStringHashcodeEquals.isSelected());
        generatorConfig.setAnnotation(annotationCheckBox.isSelected());
        generatorConfig.setUseActualColumnNames(useActualColumnNamesCheckbox.isSelected());
        generatorConfig.setXmlWithMapperCheckBoxChecked(xmlWithMapperCheckBox.isSelected());
        generatorConfig.setXmlWithAnnotationCheckBoxChecked(xmlWithAnnotationCheckBox.isSelected());
        return generatorConfig;
    }

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        controller = this;
        this.txtProjectDirectory.setEditable(false);
        nameColumn.setCellValueFactory(new PropertyValueFactory<>("name"));
        // 自定义操作列
        opsColumn.setCellValueFactory(new PropertyValueFactory<>("name"));

        this.configTable.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
        this.configTable.getSelectionModel().setCellSelectionEnabled(false);
        this.configTable.getSelectionModel().selectedItemProperty().addListener((observableValue, oldItem, newItem) -> this.setGeneratorConfigIntoUI(newItem));

        GeneratorConfigController configController = this;

        opsColumn.setCellFactory(cell -> new TableCell() {
            @Override
            protected void updateItem(Object item, boolean empty) {
                editableProperty().set(true);
                super.updateItem(item, empty);
                if (item == null || empty) {
                    setText(null);
                    setGraphic(null);
                } else {
                    Label label0 = new Label();
                    ImageView imageView = new ImageView("icons/use.png");
                    imageView.setAccessibleText("应用");
                    imageView.setFitHeight(15);
                    imageView.setFitWidth(20);
                    label0.setText("应用");
                    label0.setGraphic(imageView);

                    Label label2 = new Label();
                    label2.setText("删除");
                    imageView = new ImageView("icons/delete.png");
                    imageView.setFitHeight(15);
                    imageView.setFitWidth(15);
                    label2.setGraphic(imageView);
                    HBox hBox = new HBox();
                    hBox.setSpacing(10);
                    hBox.getChildren().add(label0);
                    hBox.getChildren().add(label2);
                    label0.setCursor(Cursor.HAND);
                    label2.setCursor(Cursor.HAND);
                    label0.setOnMouseClicked(event -> {
                        try {
                            // 应用配置
                            GeneratorConfig generatorConfig = ConfigHelper.loadGeneratorConfig(item.toString());
                            configController.mainController.setGeneratorConfig(generatorConfig);
                            controller.closeDialogStage();
                        } catch (Exception e) {
                            AlertUtil.showErrorAlert(e.getMessage());
                        }
                    });
                    label2.setOnMouseClicked(event -> {
                        try {
                            // 删除配置
                            _LOG.debug("item: {}", item);
                            ConfigHelper.deleteGeneratorConfig(item.toString());
                            refreshTableView();
                        } catch (Exception e) {
                            AlertUtil.showErrorAlert(e.getMessage());
                        }
                    });
                    setGraphic(hBox);
                }
            }
        });
        refreshTableView();
    }

    private void setGeneratorConfigIntoUI(GeneratorConfig generatorConfig) {
        if (generatorConfig == null)
            return;
        txtUniqueName.setText(generatorConfig.getName());
        txtProjectDirectory.setText(generatorConfig.getProjectFolder());
        txtClassPackage.setText(generatorConfig.getModelPackage());
        txtPrimaryKey.setText(generatorConfig.getGenerateKeys());
        txtClassDirectory.setText(generatorConfig.getModelPackageTargetFolder());
        txtInterfacePackage.setText(generatorConfig.getDaoPackage());
        txtInterfaceDirectory.setText(generatorConfig.getDaoTargetFolder());
        txtXmlPackage.setText(generatorConfig.getMappingXMLPackage());
        txtXmlDirectory.setText(generatorConfig.getMappingXMLTargetFolder());
        offsetLimitCheckBox.setSelected(generatorConfig.isOffsetLimit());

        commentCheckBox.setSelected(generatorConfig.isComment());
        needToStringHashcodeEquals.setSelected(generatorConfig.isNeedToStringHashcodeEquals());
        annotationCheckBox.setSelected(generatorConfig.isAnnotation());
        useActualColumnNamesCheckbox.setSelected(generatorConfig.isUseActualColumnNames());
        xmlWithMapperCheckBox.setSelected(generatorConfig.isXmlWithMapperCheckBoxChecked());
    }

    public void refreshTableView() {
        try {
            List<GeneratorConfig> configs = ConfigHelper.loadGeneratorConfigs();
            configTable.setItems(FXCollections.observableList(configs));
        } catch (Exception e) {
            AlertUtil.showErrorAlert(e.getMessage());
        }
    }
}
